﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OpenXMLProcess
{
    public class DocumentComparer
    {
        private MyDocument _doc1, _doc2;
        private Tokenization.Tokenizer _tr = null;

        public DocumentComparer()
        {
            _doc1 = new MyDocument();
            _doc2 = new MyDocument();
        }
        public DocumentComparer(Tokenization.Tokenizer tr)
        {
            _doc1 = new MyDocument();
            _doc2 = new MyDocument();
            _tr = tr;
        }

        public void openDoc1(string path)
        {
            _doc1.Open(path);
            _doc1.ExtractInfo();
        }
        public void openDoc2(string path)
        {
            _doc2.Open(path);
            _doc2.ExtractInfo();
        }
        public void closeDoc1()
        {
            _doc1.Close();
        }
        public void closeDoc2()
        {
            _doc2.Close();
        }

        public string getDoc1Text()
        {
            return _doc1.GetText();
        }
        public string getDoc2Text()
        {
            return _doc2.GetText();
        }
        public string[] getDoc1Paragraphs()
        {
            return System.Text.RegularExpressions.Regex.Split(getDoc1Text(), "\r\n");
        }
        public string[] getDoc2Paragraphs()
        {
            return System.Text.RegularExpressions.Regex.Split(getDoc2Text(), "\r\n");
        }

        public void setTokenizer(Tokenization.Tokenizer tr)
        {
            _tr = tr;
        }

        private string[] splitParagraph2Word(string para)
        {
            return System.Text.RegularExpressions.Regex.Split(para, "[.,;' ]");
        }
        private string[] splitParagraph2Key(string para)
        {
            string temp;
            try
            {
                temp = _tr.Process(para);
            }
            catch
            {
                throw new NullReferenceException("Tokenizer is null");
            }
            List<string> rs = new List<string>();
            var tt = System.Text.RegularExpressions.Regex.Matches(temp, @"\[[^\]]+\](?=\[\w+\])");
            foreach (System.Text.RegularExpressions.Match item in tt)
            {
                rs.Add(item.Value);
            }

            return rs.OrderBy(i => i).ToArray();
        }

        public List<CompareItem> compareForWord(int limitResult = 5, bool isMaxCompare = true)
        {
            List<CompareItem> ltemp = new List<CompareItem>();
            double r = 0;
            string[] _p1Temp, _p2Temp;
            string[] _doc1Paragraphs = getDoc1Paragraphs();
            string[] _doc2Paragraphs = getDoc2Paragraphs();

            foreach (var p1 in _doc1Paragraphs)
            {
                _p1Temp = splitParagraph2Word(p1);
                foreach (var p2 in _doc2Paragraphs)
                {
                    _p2Temp = splitParagraph2Word(p2);
                    r = Utilities.Utils._xauChungKhongKe(_p1Temp, _p2Temp) * 100.0f / (isMaxCompare ? Math.Max(_p1Temp.Length, _p2Temp.Length) : Math.Min(_p1Temp.Length, _p2Temp.Length));
                    ltemp.Add(new CompareItem()
                    {
                        SourceText = p1,
                        DestinationText = p2,
                        Ratio = r
                    });
                }
            }

            return ltemp.OrderByDescending(i => i.Ratio).Take(limitResult).ToList();
        }
        public List<CompareItem> compareForWord(string paragraph, int limitResult = 5, bool isMaxCompare = true)
        {
            List<CompareItem> ltemp = new List<CompareItem>();
            double r = 0;
            string[] _p1Temp, _p2Temp = splitParagraph2Word(paragraph);
            string[] _doc1Paragraphs = getDoc1Paragraphs();
            foreach (var p1 in _doc1Paragraphs)
            {
                _p1Temp = splitParagraph2Word(p1);
                r = Utilities.Utils._xauChungKhongKe(_p1Temp, _p2Temp) * 100.0f / (isMaxCompare ? Math.Max(_p1Temp.Length,_p2Temp.Length) : Math.Min(_p1Temp.Length, _p2Temp.Length));
                ltemp.Add(new CompareItem()
                {
                    SourceText = p1,
                    DestinationText = paragraph,
                    Ratio = r
                });
            }
            return ltemp.OrderByDescending(i => i.Ratio).Take(limitResult).ToList();
        }

        public List<CompareItem> compareForKey(int limitResult = 5, bool isMaxCompare = true)
        {
            List<CompareItem> ltemp = new List<CompareItem>();
            double r = 0;
            string[] _p1Temp, _p2Temp;
            string[] _doc1Paragraphs = getDoc1Paragraphs();
            string[] _doc2Paragraphs = getDoc2Paragraphs();

            foreach (var p1 in _doc1Paragraphs)
            {
                _p1Temp = splitParagraph2Key(p1);
                foreach (var p2 in _doc2Paragraphs)
                {
                    _p2Temp = splitParagraph2Key(p2);
                    r = Utilities.Utils._xauChungKhongKe(_p1Temp, _p2Temp) * 100.0f / (isMaxCompare ? Math.Max(_p1Temp.Length, _p2Temp.Length) : Math.Min(_p1Temp.Length, _p2Temp.Length));
                    ltemp.Add(new CompareItem()
                    {
                        SourceText = p1,
                        DestinationText = p2,
                        Ratio = r
                    });
                }
            }

            return ltemp.OrderByDescending(i => i.Ratio).Take(limitResult).ToList();
        }
        public List<CompareItem> compareForKey(string paragraph, int limitResult = 5, bool isMaxCompare = true)
        {
            List<CompareItem> ltemp = new List<CompareItem>();
            double r = 0;
            string[] _p1Temp, _p2Temp = splitParagraph2Key(paragraph);
            string[] _doc1Paragraphs = getDoc1Paragraphs();
            foreach (var p1 in _doc1Paragraphs)
            {
                _p1Temp = splitParagraph2Key(p1);
                r = Utilities.Utils._xauChungKhongKe(_p1Temp, _p2Temp) * 100.0f / (isMaxCompare ? Math.Max(_p1Temp.Length, _p2Temp.Length) : Math.Min(_p1Temp.Length, _p2Temp.Length));
                ltemp.Add(new CompareItem()
                {
                    SourceText = p1,
                    DestinationText = paragraph,
                    Ratio = r
                });
            }
            return ltemp.OrderByDescending(i => i.Ratio).Take(limitResult).ToList();
        }
    }
    public class CompareItem
    {
        public string SourceText { get; set; }
        public string DestinationText { get; set; }
        public double Ratio { get; set; }
    }
}
